package com.gopay.bis.manager.bank.expay;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;

import com.gopay.bis.common.util.BankLogUtils;
import com.gopay.bis.common.util.DateUtils;
import com.gopay.bis.common.util.TransUtils;
import com.gopay.bis.dao.bankorder.BankContractSerialInfoDAO;
import com.gopay.bis.manager.bank.BankAuthOrderManager;
import com.gopay.common.constants.bank.BankConstants;
import com.gopay.common.constants.bank.BankContractConstants;
import com.gopay.common.constants.bank.BisBankBusinessProd;
import com.gopay.common.constants.bank.CmbcConstants;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.cps.manager.order.CpsGeneralMainOrderQueryManager;
import com.gopay.common.domain.bank.BankAuthOrder;
import com.gopay.common.domain.bank.ExPayBaseMessage;
import com.gopay.common.domain.bank.cmbc.expay.CmbcExPayMessage;
import com.gopay.common.domain.bank.cmbc.expay.certification.CmbcAdPayCertification;
import com.gopay.common.domain.bank.cmbc.expay.certification.CmbcAdPayCertificationQuery;
import com.gopay.common.domain.bank.cmbc.expay.crossbank.CmbcAdPayCBankMessage;
import com.gopay.common.domain.bank.cmbc.expay.crossbank.CmbcAdPayCBankQuery;
import com.gopay.common.domain.bank.cmbc.expay.samebank.CmbcAdPayMessage;
import com.gopay.common.domain.bank.cmbc.expay.samebank.CmbcAdPayQueryMessage;
import com.gopay.common.domain.bank.cmbc.expay.whitelist.CmbcAdPayWhiteList;
import com.gopay.common.domain.bis.BisBankContractSerialInfo;
import com.gopay.common.domain.cps.CpsGenMainOrder;
import com.gopay.common.exception.GopayException;
import com.gopay.common.util.MD5Util;
import com.gopay.remote.bank.businesses.ExPayService;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;
import com.thoughtworks.xstream.io.xml.XmlFriendlyNameCoder;

/**
 * 民生代扣报文组装
 * 
 * @CmbcAdPayManager.java
 * @author zhengxue
 * @2015-11-9 上午11:10:31 www.gopay.com.cn Inc.All rights reserved.
 */
public class CmbcAdPayManager {
    @Resource(name = "cmbcConfig")
    private Map<String, String> cmbcConfig;

    @Resource(name = "bankInsCode")
    private Map<String, String> bankInsCode;

    @Resource(name = "cmbcAdPayServiceClient")
    private ExPayService cmbcAdPayServiceClient;

    @Resource(name = "bankContractSerialInfoDAO")
    private BankContractSerialInfoDAO bankContractSerialInfoDAO;

    @Resource(name = "cpsGeneralMainOrderQueryManager")
    private CpsGeneralMainOrderQueryManager mainOrderQuery;

    @Resource(name = "bankAuthOrderManager")
    private BankAuthOrderManager bankAuthOrderManager;

    private final static String XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";

    /**
     * 平台发送实名身份认证请求
     * 
     * @param message
     * @return
     * @throws GopayException
     * @throws InterruptedException
     */
    public Object certification(CmbcExPayMessage message) throws GopayException, InterruptedException {
        message.setSpecial2("certificate"); // 记录签约表信息描述
        if (isExistCardInfo(message)) {
            // 鉴权成功过
            message.setFlag(true); // 验签成功
            message.setRetType(CmbcConstants.RESP_TYPE_SUCCESS);
            message.setValidStatus(CmbcConstants.VALIDATE_STATUS_SUCCESS);
            //只有内部交易码是00664的交易，才修改认证订单表
            if (StringUtils.isNotBlank(message.getOrderId())) {
                CpsGenMainOrder mainOrder = mainOrderQuery.get(message.getOrderId());
                if ((null != mainOrder)&&(IntTxnCd._00664.value.equals(mainOrder.getGopayIntTxnCd()))) {
                    BisBankContractSerialInfo bbcs = getContractInfoByCard(message);
                    message.setAgrmtNo(bbcs.getSerialNumber());
                    // 新增方法，更改认证订单的银行订单号
                    updateBankOrderIdByOrderId(message);
                }
            }
            BankLogUtils.printExPayManagerCertificationReturnLog(message);
            return message;
        }

        String reqXml = buildCertification(message);
        message.setPlainMessage(reqXml);
        message.setXmlLength(getXmlLen(reqXml));
        String partnerId = cmbcConfig.get("CMBC.ADPAY.PARTNERID");
        message.setPartnerId(getPartnerId(partnerId));
        String txnCode = getTxnCode(cmbcConfig.get("CMBC.ADPAY.CERTIFICATION.TXNCODE")); // 8位交易码
        message.setTxnCode(txnCode);
        message.setSighLength(cmbcConfig.get("CMBC.ADPAY.SIGHLENGTH"));

        BankLogUtils.printExPayManagerCertificationSendLog(message);
        // 鉴权请求改为异步处理机制 add by zhengxue
        saveContract(message); // 记录实名认证信息
        //只有内部交易码是00664的交易，才修改认证订单表
        if (StringUtils.isNotBlank(message.getOrderId())) {
            CpsGenMainOrder mainOrder = mainOrderQuery.get(message.getOrderId());
            if (mainOrder !=null && IntTxnCd._00664.value.equals(mainOrder.getGopayIntTxnCd())) {
                // 新增方法，更改认证订单的银行订单号
                updateBankOrderIdByOrderId(message);
            }
        }
        cmbcAdPayServiceClient.certification(message); // 发起实名认证请求
        // 循环查询鉴权信息
        for (int i = 0; i < 5; i++) {
            BisBankContractSerialInfo certiInfo = getContractInfoBySerialNum(message);
            if (BankContractConstants.CONTRACT_SUCCESS.equals(certiInfo.getContractState())) {
                // 鉴权成功
                message.setFlag(true); // 验签成功
                message.setRetType(CmbcConstants.RESP_TYPE_SUCCESS);
                message.setValidStatus(CmbcConstants.VALIDATE_STATUS_SUCCESS);
                break;
            }
            Thread.sleep(1000);
        }
        BankLogUtils.printExPayManagerCertificationReturnLog(message);
        return message;
    }

    /**
     * 平台发送代扣请求
     * 
     * @param message
     * @return
     * @throws GopayException
     * @throws InterruptedException
     */
    public Object payment(CmbcExPayMessage message) throws GopayException, InterruptedException {
        String reqXml = ""; // 代扣请求报文
        String partnerId = ""; // 合作方编号
        String txnCode = ""; // 交易码
        if (BankConstants.BANK_LOGO_CMBC.equals(message.getBank())) {
            // 同行代扣
            reqXml = sameBankPay(message);
            partnerId = getSPartnerId(cmbcConfig.get("CMBC.ADPAY.PARTNERID")); // 15合作方编号
            txnCode = getTxnCode(cmbcConfig.get("CMBC.ADPAY.SAME.TXNCODE")); // 8位交易码
        } else {
            // 跨行代扣
            // 发起代扣请求前查询白名单采集状态(民生本行不需要) add by zhengxue
            if (!isSendWhiteList(message)) {
                // 白名单采集未通过
                return message;
            }

            reqXml = crossBankPay(message);
            partnerId = getPartnerId(cmbcConfig.get("CMBC.ADPAY.PARTNERID")); // 8位合作方编号
            txnCode = getTxnCode(cmbcConfig.get("CMBC.ADPAY.CROSS.TXNCODE")); // 8位交易码
        }
        message.setPlainMessage(reqXml);
        message.setXmlLength(getXmlLen(reqXml)); // 8位报文长度
        message.setPartnerId(partnerId);
        message.setTxnCode(txnCode);
        message.setSighLength(cmbcConfig.get("CMBC.ADPAY.SIGHLENGTH")); // 4位签名域长度
        BankLogUtils.printExPayManagerPaymentSendLog(message);

        // 代扣请求改为异步处理机制 add by zhengxue
        cmbcAdPayServiceClient.payment(message);
        message.setFlag(true); // 验签成功
        // BankLogUtils.printExPayManagerPaymentReturnLog(resMsg);
        return message;
    }

    /**
     * 平台发送代扣查询请求
     * 
     * @param message
     * @return
     * @throws GopayException
     */
    public Object query(CmbcExPayMessage message) throws GopayException {
        String reqQueryXml = ""; // 交易查询请求报文
        String partnerId = ""; // 合作方编号
        String txnCode = ""; // 交易码
        String bankBusProd = message.getBankBusProd().value;
        if ((BisBankBusinessProd._19.value).equals(bankBusProd)) {
            // 鉴权查询
            reqQueryXml = certificationQuery(message);
            partnerId = getPartnerId(cmbcConfig.get("CMBC.ADPAY.PARTNERID")); // 8位合作方编号
            txnCode = getTxnCode(cmbcConfig.get("CMBC.ADPAY.CERTIFICATION.QUERY.TXNCODE")); // 8位交易码
        } else if ((BisBankBusinessProd._15.value).equals(bankBusProd)
                && BankConstants.BANK_LOGO_CMBC.equals(message.getBank())) {
            // 同行代扣查询
            reqQueryXml = sameBankQuery(message);
            partnerId = getSPartnerId(cmbcConfig.get("CMBC.ADPAY.PARTNERID")); // 15合作方编号
            txnCode = getTxnCode(cmbcConfig.get("CMBC.ADPAY.SAME.QUERY.TXNCODE")); // 8位交易码
        } else {
            // 跨行代扣查询
            reqQueryXml = crossBankQuery(message);
            partnerId = getPartnerId(cmbcConfig.get("CMBC.ADPAY.PARTNERID")); // 8位合作方编号
            txnCode = getTxnCode(cmbcConfig.get("CMBC.ADPAY.CROSS.QUERY.TXNCODE")); // 8位交易码
        }
        message.setPlainMessage(reqQueryXml);
        message.setXmlLength(getXmlLen(reqQueryXml)); // 8位报文长度
        message.setPartnerId(partnerId);
        message.setTxnCode(txnCode);
        message.setSighLength(cmbcConfig.get("CMBC.ADPAY.SIGHLENGTH")); // 4位签名域长度
        BankLogUtils.printExPayManagerQuerySendLog(message);

        // 查询请求改为异步处理机制 add by zhengxue
        cmbcAdPayServiceClient.queryOrder(message);
        message.setFlag(true); // 验签成功
        // BankLogUtils.printExPayManagerQueryReturnLog(resMsg);
        return message;
    }

    /**
     * 白名单采集请求
     * 
     * @param message
     * @return
     * @throws GopayException
     * @throws InterruptedException
     */
    public boolean isSendWhiteList(CmbcExPayMessage message) throws GopayException, InterruptedException {
        boolean isWhiteList = false;
        message.setSpecial2("whiteList");// 记录签约表信息描述
        if (isExistCardInfo(message)) {
            // 白名单采集成功过
            isWhiteList = true;
        } else {
            // 未白名单采集成功过
            String reqWXml = buildWhiteList(message);
            message.setPlainMessage(reqWXml);
            message.setXmlLength(getXmlLen(reqWXml));
            message.setPartnerId(getPartnerId(cmbcConfig.get("CMBC.ADPAY.PARTNERID")));
            message.setTxnCode(getTxnCode(cmbcConfig.get("CMBC.ADPAY.WHITELIST.TXNCODE")));// 8位交易码
            message.setSighLength(cmbcConfig.get("CMBC.ADPAY.SIGHLENGTH"));
            BankLogUtils.printExPayManagerWhiteListSendLog(message);

            // 白名单采集请求改为异步处理机制 add by zhengxue
            saveContract(message); // 记录白名单采集信息
            cmbcAdPayServiceClient.certification(message); // 发起白名单采集请求
            // 循环查询白名单采集信息
            for (int i = 0; i < 5; i++) {
                BisBankContractSerialInfo whiteListInfo = getContractInfoBySerialNum(message);
                if (BankContractConstants.CONTRACT_SUCCESS.equals(whiteListInfo.getContractState())) {
                    // 白名单采集成功
                    isWhiteList = true;
                    break;
                }
                Thread.sleep(1000);
            }
            BankLogUtils.printExPayManagerCertificationReturnLog(message);
        }
        return isWhiteList;
    }

    /**
     * 组装认证请求报文
     * 
     * @param message
     * @return
     */
    private String buildCertification(CmbcExPayMessage message) {
        CmbcAdPayCertification cMessage = new CmbcAdPayCertification();
        cMessage.setVersion(cmbcConfig.get("CMBC.ADPAY.VERSION"));
        cMessage.setTransDate(DateUtils.getLocalFullDateTime14().substring(0, 8));
        cMessage.setTransTime(DateUtils.getLocalFullDateTime14().substring(8));
        // 生成唯一认证流水号
        String serialNo = DateUtils.getLocalFullDateTime14().substring(0, 8) + getShortUuid();
        message.setAgrmtNo(serialNo); // 记录身份认证请求银行流水号
        cMessage.setSerialNo(serialNo);
        cMessage.setMerId("");
        cMessage.setMerName("");
        cMessage.setBankCardType(cmbcConfig.get("CMBC.ADPAY.CARDTYPE")); // 借记卡
        cMessage.setAccNo(message.getCardNo());
        cMessage.setAccName(message.getCardHolder());
        cMessage.setCertType(cmbcConfig.get("CMBC.ADPAY.CERTTYPE")); // 身份证
        cMessage.setCertNo(message.getIdentityCode());
        cMessage.setPhone(message.getMediaId());
        cMessage.setPayerBankInsCode(getDatas(message.getBank()));
        cMessage.setProvNo("");
        cMessage.setResv("");

        XStream xs = new XStream(new DomDriver());
        xs.autodetectAnnotations(true);
        String plain = xs.toXML(cMessage);
        StringBuffer xml = new StringBuffer(XML_HEADER);
        xml.append(plain);
        String fullXml = xml.toString();

        fullXml = fullXml.replaceAll("\n", "").replaceAll("\r", "");
        return fullXml;
    }

    /**
     * 组装白名单采集请求报文
     * 
     * @param message
     * @return
     */
    private String buildWhiteList(CmbcExPayMessage message) {
        CmbcAdPayWhiteList wMessage = new CmbcAdPayWhiteList();
        wMessage.setVersion(cmbcConfig.get("CMBC.ADPAY.VERSION"));
        wMessage.setTransDate(DateUtils.getLocalFullDateTime14().substring(0, 8));
        wMessage.setTransTime(DateUtils.getLocalFullDateTime14().substring(8));
        // 生成唯一认证流水号
        String serialNo = DateUtils.getLocalFullDateTime14().substring(0, 8) + getShortUuid();
        message.setAgrmtNo(serialNo); // 记录白名单采集请求银行流水号
        wMessage.setSerialNo(serialNo);
        wMessage.setMerId("");
        wMessage.setMerName("");
        wMessage.setBankInsCode(bankInsCode.get(message.getBank()));
        wMessage.setBankName(cmbcConfig.get(message.getBank()));
        wMessage.setBankAccNo(message.getCardNo());
        wMessage.setBankAccName(message.getCardHolder());
        wMessage.setBankAccType(cmbcConfig.get("CMBC.ADPAY.CARDTYPE")); // 借记卡
        wMessage.setCertType(cmbcConfig.get("CMBC.ADPAY.CERTTYPE")); // 身份证
        wMessage.setCertNo(message.getIdentityCode());
        wMessage.setMobile(message.getMediaId());
        wMessage.setAddress("");
        wMessage.setEmail("");

        XStream xs = new XStream(new DomDriver());
        xs.autodetectAnnotations(true);
        String plain = xs.toXML(wMessage);
        StringBuffer xml = new StringBuffer(XML_HEADER);
        xml.append(plain);
        String fullXml = xml.toString();

        fullXml = fullXml.replaceAll("\n", "").replaceAll("\r", "");
        return fullXml;
    }

    /**
     * 组装同行代扣请求报文
     * 
     * @param message
     * @return
     */
    private String sameBankPay(CmbcExPayMessage message) {
        CmbcAdPayMessage sameBankMsg = new CmbcAdPayMessage();
        sameBankMsg.setVersion(cmbcConfig.get("CMBC.ADPAY.VERSION"));
        sameBankMsg.setMchntCd(cmbcConfig.get("CMBC.ADPAY.MCHNTCD"));
        sameBankMsg.setMchntName(cmbcConfig.get("CMBC.ADPAY.MCHNTNAME"));
        sameBankMsg.setTranDate(message.getOrderDate().substring(0, 8));
        sameBankMsg.setTranTime(message.getOrderDate().substring(8));
        sameBankMsg.setTranId(message.getBankOrderId());
        sameBankMsg.setBusiType("");
        sameBankMsg.setBusiNo("");
        sameBankMsg.setCurrency(cmbcConfig.get("CMBC.ADPAY.CURRENCY"));
        sameBankMsg.setAccNo(message.getCardNo());
        sameBankMsg.setAccName(message.getCardHolder());
        sameBankMsg.setPayerPhone(message.getMediaId());
        sameBankMsg.setTransAmt(TransUtils.amountConvert2Fen(message.getAmount().toString()));
        sameBankMsg.setCertType(cmbcConfig.get("CMBC.ADPAY.CERTTYPE")); // 身份证
        sameBankMsg.setCertNo(message.getIdentityCode());
        sameBankMsg.setChkFlag(cmbcConfig.get("CMBC.ADPAY.CHKFLAG")); // 户名且证件
        sameBankMsg.setRemark("");
        sameBankMsg.setResv("");

        XStream xs = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
        // XStream xs = new XStream(new DomDriver());
        xs.autodetectAnnotations(true);
        String plain = xs.toXML(sameBankMsg);
        StringBuffer xml = new StringBuffer(XML_HEADER);
        xml.append(plain);
        String fullXml = xml.toString();

        fullXml = fullXml.replaceAll("\n", "").replaceAll("\r", "");
        return fullXml;
    }

    /**
     * 组装跨行代扣请求报文
     * 
     * @param message
     * @return
     */
    private String crossBankPay(CmbcExPayMessage message) {
        CmbcAdPayCBankMessage crossBankMsg = new CmbcAdPayCBankMessage();
        crossBankMsg.setVersion(cmbcConfig.get("CMBC.ADPAY.VERSION"));
        crossBankMsg.setTransDate(message.getOrderDate().substring(0, 8));
        crossBankMsg.setTransTime(message.getOrderDate().substring(8));
        crossBankMsg.setSerialNo(message.getBankOrderId());
        crossBankMsg.setMerId(cmbcConfig.get("CMBC.ADPAY.MERID"));
        crossBankMsg.setMerName(cmbcConfig.get("CMBC.ADPAY.MERNAME"));
        crossBankMsg.setBizType(cmbcConfig.get("CMBC.ADPAY.BIZTYPE"));
        crossBankMsg.setBizNo("");
        crossBankMsg.setBizObjType(cmbcConfig.get("CMBC.ADPAY.BIZOBJTYPE")); // 对私
        crossBankMsg.setPayerAcc(message.getCardNo());
        crossBankMsg.setPayerName(message.getCardHolder());
        crossBankMsg.setBankCardType(cmbcConfig.get("CMBC.ADPAY.CARDTYPE")); // 借记卡
        crossBankMsg.setPayerBankName(cmbcConfig.get(message.getBank()));
        crossBankMsg.setPayerBankInsCode(bankInsCode.get(message.getBank()));
        crossBankMsg.setPayerBankSettleNo("");
        crossBankMsg.setPayerBankSwitchNo("");
        crossBankMsg.setPayerPhone(message.getMediaId());
        crossBankMsg.setTranAmt(TransUtils.amountConvert2Fen(message.getAmount().toString()));
        crossBankMsg.setCurrency(cmbcConfig.get("CMBC.ADPAY.CURRENCY"));
        crossBankMsg.setCertType(cmbcConfig.get("CMBC.ADPAY.CERTTYPE"));
        crossBankMsg.setCertNo(message.getIdentityCode());
        crossBankMsg.setProvNo(cmbcConfig.get("CMBC.ADPAY.PROVNO"));
        crossBankMsg.setCityNo("");
        crossBankMsg.setAgtNo("");
        crossBankMsg.setPurpose(cmbcConfig.get("CMBC.ADPAY.PURPOSE"));
        crossBankMsg.setPostscript("");

        XStream xs = new XStream(new DomDriver());
        xs.autodetectAnnotations(true);
        String plain = xs.toXML(crossBankMsg);
        StringBuffer xml = new StringBuffer(XML_HEADER);
        xml.append(plain);
        String fullXml = xml.toString();

        fullXml = fullXml.replaceAll("\n", "").replaceAll("\r", "");
        return fullXml;
    }

    /**
     * 组装同行交易查询请求报文
     * 
     * @param message
     * @return
     */
    private String sameBankQuery(CmbcExPayMessage message) {
        CmbcAdPayQueryMessage sameQueryMsg = new CmbcAdPayQueryMessage();
        sameQueryMsg.setVersion(cmbcConfig.get("CMBC.ADPAY.VERSION"));
        sameQueryMsg.setMchntCd(cmbcConfig.get("CMBC.ADPAY.MCHNTCD"));
        sameQueryMsg.setTranDate(DateUtils.getLocalFullDateTime14().substring(0, 8));
        sameQueryMsg.setTranTime(DateUtils.getLocalFullDateTime14().substring(8));
        sameQueryMsg.setTranId(message.getBankOrderId());
        sameQueryMsg.setOriTranDate(message.getOriOrderDate());
        sameQueryMsg.setOriTranId(message.getBankOrderId());
        sameQueryMsg.setResv("");

        // XStream xs = new XStream(new DomDriver());
        XStream xs = new XStream(new DomDriver("UTF-8", new XmlFriendlyNameCoder("-_", "_")));
        xs.autodetectAnnotations(true);
        String plain = xs.toXML(sameQueryMsg);
        StringBuffer xml = new StringBuffer(XML_HEADER);
        xml.append(plain);
        String fullXml = xml.toString();

        fullXml = fullXml.replaceAll("\n", "").replaceAll("\r", "");
        return fullXml;
    }

    /**
     * 组装跨行代扣查询请求报文
     * 
     * @param message
     * @return
     */
    private String crossBankQuery(CmbcExPayMessage message) {
        CmbcAdPayCBankQuery crossQuery = new CmbcAdPayCBankQuery();
        crossQuery.setVersion(cmbcConfig.get("CMBC.ADPAY.VERSION"));
        crossQuery.setTransDate(DateUtils.getLocalFullDateTime14().substring(0, 8));
        crossQuery.setTransTime(DateUtils.getLocalFullDateTime14().substring(8));
        crossQuery.setSerialNo(message.getBankOrderId());
        crossQuery.setMerId(cmbcConfig.get("CMBC.ADPAY.MERID"));
        crossQuery.setOriTransDate(message.getOriOrderDate());
        crossQuery.setOriReqSerialNo(message.getBankOrderId());
        crossQuery.setResv("");

        XStream xs = new XStream(new DomDriver());
        xs.autodetectAnnotations(true);
        String plain = xs.toXML(crossQuery);
        StringBuffer xml = new StringBuffer(XML_HEADER);
        xml.append(plain);
        String fullXml = xml.toString();

        fullXml = fullXml.replaceAll("\n", "").replaceAll("\r", "");
        return fullXml;
    }

    /**
     * 组装实名认证结果查询请求报文
     * 
     * @param message
     * @return
     */
    private String certificationQuery(CmbcExPayMessage message) {
        CmbcAdPayCertificationQuery certificationQry = new CmbcAdPayCertificationQuery();
        certificationQry.setVersion(cmbcConfig.get("CMBC.ADPAY.VERSION"));
        certificationQry.setTransDate(DateUtils.getLocalFullDateTime14().substring(0, 8));
        certificationQry.setTransTime(DateUtils.getLocalFullDateTime14().substring(8));
        certificationQry.setSerialNo(message.getBankOrderId());
        certificationQry.setMerId(cmbcConfig.get("CMBC.ADPAY.MERID"));
        certificationQry.setOriTransDate(message.getOriOrderDate());
        certificationQry.setOriReqSerialNo(message.getBankOrderId());
        certificationQry.setResv("");

        XStream xs = new XStream(new DomDriver());
        xs.autodetectAnnotations(true);
        String plain = xs.toXML(certificationQry);
        StringBuffer xml = new StringBuffer(XML_HEADER);
        xml.append(plain);
        String fullXml = xml.toString();

        fullXml = fullXml.replaceAll("\n", "").replaceAll("\r", "");
        return fullXml;
    }

    /**
     * 获取8位报文长度(右对齐左补零)
     * 
     * @param reqXml
     * @param bank
     * @return
     */
    private String getXmlLen(String reqXml) {
        try {
            // 报文长度
            String xmlLength = "";
            String xml = reqXml.replaceAll("\n", "").replaceAll("\r", "");
            xmlLength = String.valueOf(xml.getBytes("gbk").length);

            while (xmlLength.length() < 8) {
                xmlLength = "0" + xmlLength;
            }
            return xmlLength;
        } catch (UnsupportedEncodingException e) {
            BankLogUtils.printManagerExceptionLog(e);
            return null;
        }
    }

    /**
     * 获取15位合作方编号(定长15位，位数不足左补空格)
     * 
     * @param partnerId
     * @return
     */
    private String getSPartnerId(String partnerId) {
        while (partnerId.length() < 15) {
            partnerId = " " + partnerId;
        }
        return partnerId;
    }

    /**
     * 获取8位交易码(定长8位，位数不足左补空格)
     * 
     * @param txnCode
     * @return
     */
    private String getTxnCode(String txnCode) {
        while (txnCode.length() < 8) {
            txnCode = " " + txnCode;
        }
        return txnCode;
    }

    /**
     * 获取8位合作方编号(定长8位，位数不足左补空格)
     * 
     * @param partnerId
     * @return
     */
    private String getPartnerId(String partnerId) {
        while (partnerId.length() < 8) {
            partnerId = " " + partnerId;
        }
        return partnerId;
    }

    public static String[] chars = new String[] { "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
            "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8",
            "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
            "U", "V", "W", "X", "Y", "Z" };

    public static String getShortUuid() {
        StringBuffer stringBuffer = new StringBuffer();
        String uuid = UUID.randomUUID().toString().replace("-", "");
        for (int i = 0; i < 8; i++) {
            String str = uuid.substring(i * 4, i * 4 + 4);
            int strInteger = Integer.parseInt(str, 16);
            stringBuffer.append(chars[strInteger % 0x3E]);
        }

        return stringBuffer.toString();
    }

    private String getDatas(String str) {
        if (BankConstants.BANK_LOGO_ICBC.equals(str) || BankConstants.BANK_LOGO_PSBC.equals(str)
                || BankConstants.BANK_LOGO_CEB.equals(str)) {
            // 若工商、邮储、光大三家银行走认证渠道1
            return "";
        } else {
            return bankInsCode.get(str);
        }
    }

    /**
     * 校验卡信息是否鉴权或白名单采集成功过
     * 
     * @param message
     * @return
     */
    public boolean isExistCardInfo(ExPayBaseMessage message) {
        String elementsValue = MD5Util
                .sign(message.getIdentityCode() + message.getCardHolder() + message.getCardNo() + message.getMediaId());
        BisBankContractSerialInfo serialInfo = getContractInfoByCard(message);
        if (serialInfo != null && elementsValue.equals(serialInfo.getElementsValue())) {
            return true;
        }
        return false;
    }

    /**
     * 新建签约流水信息
     * 
     * @param message
     * 
     */
    public void saveContract(ExPayBaseMessage message) {
        BisBankContractSerialInfo bisBankContractSerialInfo = new BisBankContractSerialInfo();
        bisBankContractSerialInfo.setBankCode(message.getBank());
        bisBankContractSerialInfo.setBankBizProdCode(message.getBankBusProd().value);
        bisBankContractSerialInfo.setIntrfaceChannelCode(message.getBankIntrChann().value);
        bisBankContractSerialInfo.setCardNo(message.getCardNo());
        String enementsValue = MD5Util
                .sign(message.getIdentityCode() + message.getCardHolder() + message.getCardNo() + message.getMediaId());
        bisBankContractSerialInfo.setElementsValue(enementsValue);
        bisBankContractSerialInfo.setSerialNumber(message.getAgrmtNo());
        bisBankContractSerialInfo.setContractDesc(message.getSpecial2());
        bankContractSerialInfoDAO.insertContractSerialInfo(bisBankContractSerialInfo);
    }

    public void updateBankOrderIdByOrderId(ExPayBaseMessage base) {
        BankAuthOrder authOrder = new BankAuthOrder();
        authOrder.setOrderId(base.getOrderId());
        authOrder.setOutOrderId(base.getAgrmtNo());
        bankAuthOrderManager.updateAuthBankOrderIdbyOrderId(authOrder);
    }

    public void updateBankOrderIdBySerialInfo(ExPayBaseMessage base) {
        getContractInfoBySerialNum(base);
    }

    /**
     * 根据请求银行流水号获取签约流水数据
     * 
     * @param message
     * @return
     */
    public BisBankContractSerialInfo getContractInfoBySerialNum(ExPayBaseMessage message) {
        BisBankContractSerialInfo bisBankContractSerialInfo = new BisBankContractSerialInfo();
        bisBankContractSerialInfo.setBankCode(message.getBank());
        bisBankContractSerialInfo.setBankBizProdCode(message.getBankBusProd().value);
        bisBankContractSerialInfo.setIntrfaceChannelCode(message.getBankIntrChann().value);
        bisBankContractSerialInfo.setSerialNumber(message.getAgrmtNo());
        bisBankContractSerialInfo = bankContractSerialInfoDAO.getContractInfobySerialNum(bisBankContractSerialInfo);
        return bisBankContractSerialInfo;
    }

    /**
     * 根据卡号获取签约流水数据
     * 
     * @param message
     * @return
     */
    public BisBankContractSerialInfo getContractInfoByCard(ExPayBaseMessage message) {
        BisBankContractSerialInfo bisBankContractSerialInfo = new BisBankContractSerialInfo();
        bisBankContractSerialInfo.setBankCode(message.getBank());
        // bisBankContractSerialInfo.setBankBizProdCode(message.getBankBusProd().value);
        bisBankContractSerialInfo.setIntrfaceChannelCode(message.getBankIntrChann().value);
        bisBankContractSerialInfo.setCardNo(message.getCardNo());
        bisBankContractSerialInfo.setContractDesc(message.getSpecial2());
        bisBankContractSerialInfo = bankContractSerialInfoDAO.getContractInfobyCard(bisBankContractSerialInfo);
        return bisBankContractSerialInfo;
    }

}
